home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
011
/
adikit.arc
/
IWAIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-12-01
|
3KB
|
113 lines
;
; Install resident program and service interrupts
;
; This routine supports the development of installable
; programs in Lattice C. A program which is intended to be
; made an installable INT routine is written in -P model
; Lattice. After it initialises, it calls, in a processing
; loop:
;
; while (1) { /* Loop processing requests */
; iwait(<vec>, &resreg, &reqreg);
; ... process request ...
; }
;
; <vec> is the interrupt vector which will be used to call the
; installed program. RESREG and REQREG are instances of a structure
; declared as:
;
; struct regparam {
; unsigned ax, bx, cx, dx;
; };
;
; On the first call, the program will be installed and will
; remain in memory until summoned by an INT to the designated
; vector <vec>. When the INT occurs, IWAIT will return with
; REQREG containing the values in AX through DX when the INT
; was executed. After the program processes the request, it
; may load values into the RESREG structure and return to the
; IWAIT. The values in RESREG will be returned in the registers
; upon return from the caller's INT.
include dos.mac
dseg install
EXTRN _tsize:WORD
endds install
pseg
public iwait
firstime dw 1 ; first time flag
rss dw 0 ; save stack segment
rsp dw 0 ; save stack pointer
css dw 0 ; caller's stack segment
csp dw 0 ; caller's stack pointer
iwait proc far
push bp
mov bp,sp ; set our arg pointer
push ds ; save important registers
push es
push bp ; save argument pointer
cmp firstime,0 ; is this the first call ?
je insnft ; no. skip setup
mov firstime,0 ; mark not first time
mov rss,ss ; save stack segment
mov rsp,sp ; save stack pointer
mov bx,args ; load interrupt vector
shl bx,1 ; * 2
shl bx,1 ; * 4
mov ax,0 ; clear accumulator
mov es,ax ; address base page
mov cx,offset intrap ; load interrupt handler address
mov es:[bx],cx ; store trap address
mov es:[bx+2],cs ; store our segment
mov ah,31h ; load keep process code
mov al,0 ; load normal termination
mov dx,_tsize ; load length to preserve
int 21h ; terminate and stay resident
insnft: mov si,args+2 ; load source registers
mov ax,[si] ; load AX
mov bx,[si+2] ; load BX
mov cx,[si+4] ; load CX
mov dx,[si+6] ; load DX
cli ; prevent interrupts
mov ss,css ; load caller's stack segment
mov sp,csp ; load caller's stack pointer
sti ; enable interrupts
pop bp ; save base page
pop es ; restore ES
pop ds ; restore DS
iret ; return to caller
; Totally awesome! We just got an interrupt call from the
; vector. Restore the context we were running in and return
; as if from the last call.
intrap: push ds ; save user data segment
push es ; save user extra segment
push bp ; save frame pointer
mov css,ss ; save stack segment
mov csp,sp ; save stack pointer
mov ss,rss ; restore our stack segment
mov sp,rsp ; restore our stack pointer
sti ; enable interrupts
pop bp ; restore argument pointer
pop es ; restore ES
pop ds ; restore DS
cld ; set the Goddam increment bit !
mov si,args+4 ; load result register pointer
mov [si],ax ; store AX
mov [si+2],bx ; save BX
mov [si+4],cx ; save CX
mov [si+6],dx ; save DX
pop bp ; restore caller's stack frame
ret ; return
iwait endp
endps
end